package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
)

var (
	dir   = flag.String("d", "../..", "请输入路径")
	app   = flag.String("a", "system", "请输入所属服务")
	model = flag.String("m", "User,Menu,Role,Dept", "请输入Model模型")
)

type Generator struct {
	Model string
	Name  string
}

// tpler
func (o Generator) CreateFile(tpler, gofile string) (string, error) {
	filename := *dir + "/api/" + *app + "/"
	if gofile == "" {
		filename += (tpler + "/" + o.Name + ".go")
	} else {
		filename += gofile
	}
	_, err := os.Stat(filename)
	if err == nil {
		return filename, errors.New("has created")
	}
	os.MkdirAll(filepath.Dir(filename), os.ModePerm)
	file, err := os.Create(filename)
	if err != nil {
		return filename, err
	}
	b, err := os.ReadFile(fmt.Sprintf("%s/templete/%s.tpl", *dir, tpler))
	if err != nil {
		return filename, err
	}
	tplstr := strings.ReplaceAll(string(b), "{{.Model}}", o.Model)
	tplstr = strings.ReplaceAll(tplstr, "{{.App}}", *app)
	tplstr = strings.ReplaceAll(tplstr, "{{.Name}}", o.Name)
	file.WriteString(tplstr)
	file.Close()
	return filename, nil
}

func (o Generator) ModifyFile(tpler, gofile string, handler func(b []byte) string) {
	filename, err := o.CreateFile(tpler, gofile)
	if err == nil {
		return
	}
	file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0666)
	if err != nil {
		log.Fatalln(err)
	}
	b, _ := os.ReadFile(filename)
	tplstr := handler(b)
	file.WriteString(tplstr)
	file.Close()
}

func main() {
	flag.Parse()
	arr := strings.Split(*model, ",")
	for _, v := range arr {
		gr := &Generator{
			Model: v,
			Name:  strings.ToLower(v),
		}
		gr.CreateFile("controller", "")
		gr.CreateFile("model", "")
		gr.ModifyFile("dto", "dto/where.go", func(b []byte) string {
			rflags := "switch v.(type) {\n"
			rstr := rflags + "\tcase *model.%s:\n"
			return strings.ReplaceAll(string(b), rflags, fmt.Sprintf(rstr, gr.Model))
		})
		gr.ModifyFile("main", "main.go", func(b []byte) string {
			dbflags := "db.RegisterModel(\n"
			dbstr := dbflags + "\t\t&model.%s{},\n"
			rflags := "func(r *gin.RouterGroup) {\n"
			rstr := rflags + "\t\tcontroller.%s{}.Routers(r.Group(\"/%s\"))\n"
			tplstr := strings.ReplaceAll(string(b), dbflags, fmt.Sprintf(dbstr, gr.Model))
			return strings.ReplaceAll(tplstr, rflags, fmt.Sprintf(rstr, gr.Model, gr.Name))
		})
	}
}
